package org.siqisource.webstart.core.utils.condition;

import java.util.ArrayList;
import java.util.List;

import org.siqisource.webstart.core.utils.converter.NameConverter;

public class Expression {

	/** 多�?的查询条�?*/
	public static final String MULTI_VALUE_SEPARATOR = ",";
	
	/** 无�?的查询条�?*/
	public static final String CONDITION_TYPE_NO_VALUE = "noValue";
	
	/** 单个值的查询条件 */
	public static final String CONDITION_TYPE_SIGNLE_VALUE = "singleValue";
	
	/** 两个值的查询条件 */
	public static final String CONDITION_TYPE_BETWEEN_VALUE = "betweenValue";
	
	/** 多个值的查询条件 */
	public static final String CONDITION_TYPE_LIST_VALUE = "listValue";

	/** 逻辑符号 */
	private String logicalSymbol;

	/** 左括�?*/
	private String leftParenthesis;

	/** 右括�?*/
	private String rightParenthesis;

	/** 属�?�?*/
	private String propertyName;

	/** 列名 */
	private String columnName;

	/** 比较�?*/
	private String compareSymbol;

	/** �?*/
	private Object value;

	/** 第二个�? */
	private Object secondValue;

	/** 类型 */
	private String type;

	public Expression(String logicalSymbol, String leftParenthesis, String properityName, String compareSymbol,
			Object value, Object secondValue, String rightParenthesis) {

		this.logicalSymbol = " " + logicalSymbol + " ";

		this.leftParenthesis = leftParenthesis;

		this.rightParenthesis = rightParenthesis;

		this.propertyName = properityName;

		this.columnName = getColumn(properityName);

		this.compareSymbol = " " + compareSymbol + " ";

		this.value = value;

		this.secondValue = secondValue;

		this.setType();

		this.resetValue();

	}

	private void setType() {
		String lowCaseCompareSymbol = this.compareSymbol.toLowerCase();
		if (lowCaseCompareSymbol.indexOf("is") != -1) {
			this.type = CONDITION_TYPE_NO_VALUE;
		} else if (lowCaseCompareSymbol.indexOf("group") != -1) {
			this.type = CONDITION_TYPE_NO_VALUE;
		} else if (lowCaseCompareSymbol.indexOf("order") != -1) {
			this.type = CONDITION_TYPE_NO_VALUE;
		} else if (lowCaseCompareSymbol.indexOf("distinct") != -1) {
			this.type = CONDITION_TYPE_NO_VALUE;
		} else if (lowCaseCompareSymbol.indexOf("between") != -1) {
			this.type = CONDITION_TYPE_BETWEEN_VALUE;
		} else if (lowCaseCompareSymbol.indexOf("in") != -1) {
			this.type = CONDITION_TYPE_LIST_VALUE;
		} else {
			this.type = CONDITION_TYPE_SIGNLE_VALUE;
		}
	}

	public void resetValue() {
		if (this.type.equals(CONDITION_TYPE_LIST_VALUE)
				&& this.value.getClass().getName().equals(String.class.getName())) {

			String[] values = ((String) this.value).split(MULTI_VALUE_SEPARATOR);
			List<Object> valueList = new ArrayList<Object>();
			for (int i = 0; i < values.length; i++) {
				valueList.add(values[i]);
			}
		}
	}


	/**
	 * 转换为stmt(无�?辑符�?
	 * 
	 * @param index
	 * @return
	 */
	public String toStmt(int index) {

		StringBuffer result = new StringBuffer();

		result.append(this.logicalSymbol);
		
		result.append(this.leftParenthesis);
		result.append(this.columnName).append(this.compareSymbol);

		if (this.type.equals(CONDITION_TYPE_BETWEEN_VALUE)) {
			result.append("#{condition.expressions[").append(index).append("].value}");
			result.append("#{condition.expressions[").append(index).append("].secondValue}");
		} else if (this.type.equals(CONDITION_TYPE_SIGNLE_VALUE)) {
			result.append("#{condition.expressions[").append(index).append("].value}");
		} else if (this.type.equals(CONDITION_TYPE_LIST_VALUE)) {

			List<?> values = (List<?>) this.value;
			for (int i = 0, length = values.size(); i < length; i++) {
				if (i != 0) {
					result.append(" , ");
				}
				result.append("  '").append(values.get(i)).append("' ");
			}

		}
		return result.append(this.rightParenthesis).toString();
	}

	 
	public String toString() {

		StringBuffer result = new StringBuffer();

		result.append(this.leftParenthesis);
		result.append(this.columnName).append(this.compareSymbol);

		if (this.type.equals(CONDITION_TYPE_BETWEEN_VALUE)) {
			result.append(this.value).append(" and ").append(this.secondValue);
		} else if (this.type.equals(CONDITION_TYPE_SIGNLE_VALUE)) {
			result.append(this.value);
		} else if (this.type.equals(CONDITION_TYPE_LIST_VALUE)) {

			List<?> values = (List<?>) this.value;
			for (int i = 0, length = values.size(); i < length; i++) {
				if (i != 0) {
					result.append(" , ");
				}
				result.append("  '").append(values.get(i)).append("' ");
			}

		}
		return result.append(this.rightParenthesis).toString();
	}

	public String getLogicalSymbol() {
		return logicalSymbol;
	}

	public void setLogicalSymbol(String logicalSymbol) {
		this.logicalSymbol = logicalSymbol;
	}

	public String getLeftParenthesis() {
		return leftParenthesis;
	}

	public void setLeftParenthesis(String leftParenthesis) {
		this.leftParenthesis = leftParenthesis;
	}

	public String getRightParenthesis() {
		return rightParenthesis;
	}

	public void setRightParenthesis(String rightParenthesis) {
		this.rightParenthesis = rightParenthesis;
	}

	public String getPropertyName() {
		return propertyName;
	}

	public void setPropertyName(String propertyName) {
		this.propertyName = propertyName;
	}

	public String getColumnName() {
		return columnName;
	}

	public void setColumnName(String columnName) {
		this.columnName = columnName;
	}

	public String getCompareSymbol() {
		return compareSymbol;
	}

	public void setCompareSymbol(String compareSymbol) {
		this.compareSymbol = compareSymbol;
	}

	public Object getValue() {
		return value;
	}

	public void setValue(Object value) {
		this.value = value;
	}

	public Object getSecondValue() {
		return secondValue;
	}

	public void setSecondValue(Object secondValue) {
		this.secondValue = secondValue;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	private String getColumn(String property) {
		String column = "";
		if (property.indexOf("[.]") != -1) {
			String[] parts = property.split("[.]");
			column = parts[0].toLowerCase();
			property =parts[1];
		}

		return column + NameConverter.propertyToColumn(property).toLowerCase();
	}

}
